﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using CommonUtils.CommandLine;
using CommonUtils.Logging;

namespace ProcessLauncher
{
    /// <summary>
    /// Command line analyzer for process launcher
    /// </summary>
    internal class ProcessLauncherCommandLineHandler: CommandLineHandler
    {
        #region Properties

        /// <summary>
        /// Process to launch
        /// </summary>
        protected string Process
        {
            [DebuggerStepThrough]
            get;
            [DebuggerStepThrough]
            set;
        }

        /// <summary>
        /// Timeout before try start process
        /// </summary>
        protected TimeSpan? RunTimeout
        {
            [DebuggerStepThrough]
            get;
            [DebuggerStepThrough]
            set;
        }

        /// <summary>
        /// Processes to wait before start
        /// </summary>
        protected List<string> PrerequirementProcessList
        {
            [DebuggerStepThrough]
            get;
            [DebuggerStepThrough]
            set;
        }

        /// <summary>
        /// Connections to wait before start
        /// </summary>
        protected List<string> PrerequirementConnectionList
        {
            [DebuggerStepThrough]
            get;
            [DebuggerStepThrough]
            set;
        }

        #endregion

        #region Constructor

        /// <summary>
        /// Default constructor
        /// </summary>
        /// <param name="arguments">Command line arguments</param>
        public ProcessLauncherCommandLineHandler(IEnumerable<string> arguments): base(arguments)
        {
        }

        #endregion

        #region Command line arguments

        /// <summary>
        /// Handle connections to wait command line parameter
        /// </summary>
        /// <param name="value">Parameter value</param>
        [CommandLineItemDescription("Wait for specified connection before start")]
        [CommandLineArgumentHandler("wait-connection")]
        [CommandLineArgumentHandler("wc")]
        protected void WaitForConnectionArgumentHandler(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return;
            }
            if (PrerequirementConnectionList == null)
            {
                PrerequirementConnectionList = new List<string>();
            }
            PrerequirementConnectionList.Add(value);
        }

        /// <summary>
        /// Handle processes to wait command line parameter
        /// </summary>
        /// <param name="value">Parameter value</param>
        [CommandLineItemDescription("Wait for specified process before start")]
        [CommandLineArgumentHandler("wait-process")]
        [CommandLineArgumentHandler("wp")]
        protected void WaitForProcessArgumentHandler(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return;
            }
            if (PrerequirementProcessList == null)
            {
                PrerequirementProcessList = new List<string>();
            }
            PrerequirementProcessList.Add(value);
        }

        /// <summary>
        /// Handle timeout before try to launch process
        /// </summary>
        /// <param name="value">Parameter value</param>
        [CommandLineItemDescription("Timeout before try to launch process in ms")]
        [CommandLineArgumentHandler("run-timeout")]
        [CommandLineArgumentHandler("rt")]
        protected void RunTimeoutArgumentHandler(string value)
        {
            int longValue;
            if (int.TryParse(value, out longValue))
            {
                RunTimeout = new TimeSpan(0, 0, 0, 0, longValue);
            }
            else
            {
                Logger.Instance.LogMessage(MessageType.Error, string.Format("Incorrect value of timeout: {0}", value));
            }
        }

        /// <summary>
        /// Process to launch
        /// </summary>
        /// <param name="value">Parameter value</param>
        [CommandLineItemDescription("Process to launch (absolute or relative file name)")]
        [CommandLineArgumentHandler("process")]
        [CommandLineArgumentHandler("p")]
        protected void ProcessArgumentHandler(string value)
        {
            if (string.IsNullOrEmpty(value))
            {
                return;
            }
            DefaultCommand = RunCommandHandler;
            Process = value;
        }

        #endregion

        #region Command line commands

        /// <summary>
        /// Run specified process
        /// </summary>
        [CommandLineItemDescription("Run specified process")]
        [CommandLineCommandHandler("run")]
        [CommandLineCommandHandler("r")]
        protected void RunCommandHandler()
        {
            ProcessLauncher.Instance.Launch(Process,
                                            null,
                                            RunTimeout,
                                            PrerequirementProcessList,
                                            PrerequirementConnectionList,
                                            null,
                                            null);
        }

        #endregion
    }
}